﻿package com.rbac.system.service.impl;

import com.rbac.system.common.Result;
import com.rbac.system.dto.MenuDTO;
import com.rbac.system.entity.Menu;
import com.rbac.system.mapper.MenuMapper;
import com.rbac.system.mapper.RoleMenuMapper;
import com.rbac.system.service.MenuManagementService;
import com.rbac.system.vo.MenuManagementVO;
import com.rbac.system.vo.MenuDocumentationVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MenuManagementServiceImpl implements MenuManagementService {
    
    @Autowired
    private MenuMapper menuMapper;
    
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    
    @Override
    public Result<List<MenuManagementVO>> getAllMenusTree() {
        try {
            // 获取所有菜单（包括禁用的）
            List<Menu> menus = menuMapper.selectByTypeAndStatus(null, null);
            List<MenuManagementVO> menuVOs = menus.stream().map(this::convertToVO).collect(Collectors.toList());
            
            // 构建菜单树
            List<MenuManagementVO> menuTree = buildMenuTree(menuVOs, 0L);
            return Result.success(menuTree);
        } catch (Exception e) {
            return Result.error("获取菜单树失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<MenuManagementVO>> getAllMenusList() {
        try {
            // 获取所有菜单（包括禁用的）
            List<Menu> menus = menuMapper.selectByTypeAndStatus(null, null);
            List<MenuManagementVO> menuVOs = menus.stream().map(this::convertToVO).collect(Collectors.toList());
            
            // 按排序字段排序
            menuVOs.sort((a, b) -> {
                if (a.getSort() == null) a.setSort(0);
                if (b.getSort() == null) b.setSort(0);
                return a.getSort().compareTo(b.getSort());
            });
            
            return Result.success(menuVOs);
        } catch (Exception e) {
            return Result.error("获取菜单列表失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<MenuManagementVO> getMenuById(Long id) {
        try {
            Menu menu = menuMapper.selectById(id);
            if (menu == null) {
                return Result.error("菜单不存在");
            }
            
            MenuManagementVO menuVO = convertToVO(menu);
            return Result.success(menuVO);
        } catch (Exception e) {
            return Result.error("获取菜单详情失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> addMenu(MenuDTO menuDTO) {
        try {
            // 检查菜单编码是否重复
            Menu existingMenu = menuMapper.selectList(new Menu() {{
                setMenuCode(menuDTO.getMenuCode());
            }}).stream().findFirst().orElse(null);
            
            if (existingMenu != null) {
                return Result.error("菜单编码已存在");
            }
            
            // 转换为实体
            Menu menu = convertToEntity(menuDTO);
            menu.setCreateTime(LocalDateTime.now());
            menu.setUpdateTime(LocalDateTime.now());
            menu.setDeleted(0);
            
            // 如果没有设置状态，默认为启用
            if (menu.getStatus() == null) {
                menu.setStatus(1);
            }
            
            // 如果没有设置排序，默认为0
            if (menu.getSort() == null) {
                menu.setSort(0);
            }
            
            // 如果父级ID为空或0，设置为0
            if (menu.getParentId() == null) {
                menu.setParentId(0L);
            }
            
            menuMapper.insert(menu);
            return Result.success();
        } catch (Exception e) {
            return Result.error("新增菜单失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> updateMenu(Long id, MenuDTO menuDTO) {
        try {
            // 检查菜单是否存在
            Menu existingMenu = menuMapper.selectById(id);
            if (existingMenu == null) {
                return Result.error("菜单不存在");
            }
            
            // 检查菜单编码是否重复（排除自己）
            List<Menu> menusWithSameCode = menuMapper.selectList(new Menu() {{
                setMenuCode(menuDTO.getMenuCode());
            }});
            
            boolean codeExists = menusWithSameCode.stream()
                    .anyMatch(menu -> !menu.getId().equals(id));
            
            if (codeExists) {
                return Result.error("菜单编码已存在");
            }
            
            // 检查是否将自己设置为自己的父级
            if (menuDTO.getParentId() != null && menuDTO.getParentId().equals(id)) {
                return Result.error("不能将自己设置为父级菜单");
            }
            
            // 转换为实体
            Menu menu = convertToEntity(menuDTO);
            menu.setId(id);
            menu.setUpdateTime(LocalDateTime.now());
            
            // 如果父级ID为空，设置为0
            if (menu.getParentId() == null) {
                menu.setParentId(0L);
            }
            
            menuMapper.updateById(menu);
            return Result.success();
        } catch (Exception e) {
            return Result.error("更新菜单失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> deleteMenu(Long id) {
        try {
            // 检查菜单是否存在
            Menu menu = menuMapper.selectById(id);
            if (menu == null) {
                return Result.error("菜单不存在");
            }
            
            // 检查是否有子菜单
            List<Menu> childMenus = menuMapper.selectList(new Menu() {{
                setParentId(id);
            }});
            
            if (!childMenus.isEmpty()) {
                return Result.error("存在子菜单，无法删除");
            }
            
            // 删除角色菜单关联
            roleMenuMapper.deleteByMenuId(id);
            
            // 删除菜单
            menuMapper.deleteById(id);
            
            return Result.success();
        } catch (Exception e) {
            return Result.error("删除菜单失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<MenuManagementVO>> getParentMenuOptions() {
        try {
            // 获取所有目录和菜单类型的菜单（不包括按钮）
            List<Menu> menus = menuMapper.selectList(new Menu() {{
                setStatus(1);
            }}).stream()
                    .filter(menu -> "DIRECTORY".equals(menu.getMenuType()) || "MENU".equals(menu.getMenuType()))
                    .collect(Collectors.toList());
            
            List<MenuManagementVO> menuVOs = menus.stream().map(this::convertToVO).collect(Collectors.toList());
            
            // 构建菜单树
            List<MenuManagementVO> menuTree = buildMenuTree(menuVOs, 0L);
            return Result.success(menuTree);
        } catch (Exception e) {
            return Result.error("获取父级菜单选项失败：" + e.getMessage());
        }
    }
    
    /**
     * 转换为VO
     */
    private MenuManagementVO convertToVO(Menu menu) {
        MenuManagementVO vo = new MenuManagementVO();
        BeanUtils.copyProperties(menu, vo);
        return vo;
    }
    
    /**
     * 转换为实体
     */
    private Menu convertToEntity(MenuDTO dto) {
        Menu menu = new Menu();
        BeanUtils.copyProperties(dto, menu);
        return menu;
    }
    
    /**
     * 构建菜单树
     */
    private List<MenuManagementVO> buildMenuTree(List<MenuManagementVO> menus, Long parentId) {
        return menus.stream()
                .filter(menu -> {
                    if (parentId == null || parentId == 0) {
                        return menu.getParentId() == null || menu.getParentId() == 0;
                    } else {
                        return parentId.equals(menu.getParentId());
                    }
                })
                .map(menu -> {
                    menu.setChildren(buildMenuTree(menus, menu.getId()));
                    return menu;
                })
                .sorted((a, b) -> {
                    if (a.getSort() == null) a.setSort(0);
                    if (b.getSort() == null) b.setSort(0);
                    return a.getSort().compareTo(b.getSort());
                })
                .collect(Collectors.toList());
    }
    
    @Override
    public Result<MenuDocumentationVO> getMenuDocumentation() {
        try {
            MenuDocumentationVO documentation = new MenuDocumentationVO();
            
            // 获取所有菜单数据
            List<Menu> allMenus = menuMapper.selectByTypeAndStatus(null, null);
            
            // 统计信息
            MenuDocumentationVO.MenuStatistics statistics = new MenuDocumentationVO.MenuStatistics();
            statistics.setTotalMenus(allMenus.size());
            statistics.setDirectoryCount((int) allMenus.stream().filter(m -> "DIRECTORY".equals(m.getMenuType())).count());
            statistics.setMenuCount((int) allMenus.stream().filter(m -> "MENU".equals(m.getMenuType())).count());
            statistics.setButtonCount((int) allMenus.stream().filter(m -> "BUTTON".equals(m.getMenuType())).count());
            statistics.setEnabledCount((int) allMenus.stream().filter(m -> m.getStatus() == 1).count());
            statistics.setDisabledCount((int) allMenus.stream().filter(m -> m.getStatus() == 0).count());
            documentation.setStatistics(statistics);
            
            // 构建菜单树（使用现有的菜单数据）
            List<MenuManagementVO> menuVOs = allMenus.stream().map(this::convertToVO).collect(Collectors.toList());
            List<MenuManagementVO> menuTree = buildMenuTree(menuVOs, 0L);
            
            // 转换为文档格式
            List<MenuDocumentationVO.MenuDocumentationItemVO> docMenuTree = menuTree.stream()
                    .map(this::convertToDocumentationItem)
                    .collect(Collectors.toList());
            documentation.setMenuTree(docMenuTree);
            
            // 菜单类型说明文档
            List<MenuDocumentationVO.MenuTypeDocVO> typeDocuments = createMenuTypeDocuments();
            documentation.setMenuTypeDocuments(typeDocuments);
            
            return Result.success(documentation);
        } catch (Exception e) {
            return Result.error("获取菜单说明文档失败：" + e.getMessage());
        }
    }
    
    /**
     * 转换为文档菜单项
     */
    private MenuDocumentationVO.MenuDocumentationItemVO convertToDocumentationItem(MenuManagementVO menu) {
        MenuDocumentationVO.MenuDocumentationItemVO item = new MenuDocumentationVO.MenuDocumentationItemVO();
        item.setId(menu.getId());
        item.setMenuName(menu.getMenuName());
        item.setMenuCode(menu.getMenuCode());
        item.setMenuType(menu.getMenuType());
        item.setPath(menu.getPath());
        item.setComponent(menu.getComponent());
        item.setIcon(menu.getIcon());
        item.setSort(menu.getSort());
        item.setStatus(menu.getStatus());
        item.setDescription(menu.getDescription());
        
        // 递归转换子菜单
        if (menu.getChildren() != null && !menu.getChildren().isEmpty()) {
            List<MenuDocumentationVO.MenuDocumentationItemVO> children = menu.getChildren().stream()
                    .map(this::convertToDocumentationItem)
                    .collect(Collectors.toList());
            item.setChildren(children);
        }
        
        return item;
    }
    
    /**
     * 创建菜单类型说明文档
     */
    private List<MenuDocumentationVO.MenuTypeDocVO> createMenuTypeDocuments() {
        List<MenuDocumentationVO.MenuTypeDocVO> documents = Arrays.asList(
            createDirectoryTypeDoc(),
            createMenuTypeDoc(),
            createButtonTypeDoc()
        );
        return documents;
    }
    
    /**
     * 创建目录类型说明
     */
    private MenuDocumentationVO.MenuTypeDocVO createDirectoryTypeDoc() {
        MenuDocumentationVO.MenuTypeDocVO doc = new MenuDocumentationVO.MenuTypeDocVO();
        doc.setType("DIRECTORY");
        doc.setTypeName("目录");
        doc.setDescription("用于组织和分类菜单，不对应具体页面，主要起到分组作用");
        doc.setUsage("适用于模块分组，如'系统管理'、'课程管理'等，在左侧菜单中显示为可展开的父级菜单");
        doc.setExamples(Arrays.asList(
            "系统管理 - 包含用户管理、角色管理等子菜单",
            "课程管理 - 包含课程模板、开课申请等子菜单",
            "成绩管理 - 包含成绩录入、成绩审核等子菜单"
        ));
        doc.setNotes("目录类型不需要配置组件路径，路由路径可选，主要用于菜单层级组织");
        return doc;
    }
    
    /**
     * 创建菜单类型说明
     */
    private MenuDocumentationVO.MenuTypeDocVO createMenuTypeDoc() {
        MenuDocumentationVO.MenuTypeDocVO doc = new MenuDocumentationVO.MenuTypeDocVO();
        doc.setType("MENU");
        doc.setTypeName("菜单");
        doc.setDescription("对应具体的页面组件，用户点击后会导航到相应的页面");
        doc.setUsage("适用于具体功能页面，需要配置路由路径和组件路径，在左侧菜单中显示为可点击的菜单项");
        doc.setExamples(Arrays.asList(
            "用户管理 - 路径: /system/user, 组件: UserManagement",
            "角色管理 - 路径: /system/role, 组件: RoleManagement",
            "菜单管理 - 路径: /system/menu, 组件: MenuManagement"
        ));
        doc.setNotes("菜单类型必须配置路由路径和组件路径，组件路径对应前端的Vue组件名称");
        return doc;
    }
    
    /**
     * 创建按钮类型说明
     */
    private MenuDocumentationVO.MenuTypeDocVO createButtonTypeDoc() {
        MenuDocumentationVO.MenuTypeDocVO doc = new MenuDocumentationVO.MenuTypeDocVO();
        doc.setType("BUTTON");
        doc.setTypeName("按钮权限");
        doc.setDescription("用于控制页面内具体操作的权限，不在左侧菜单中显示，通过权限控制页面按钮的可见性");
        doc.setUsage("适用于页面内的操作权限控制，如新增、编辑、删除等按钮的显示权限");
        doc.setExamples(Arrays.asList(
            "新增用户 - 权限码: user:add",
            "编辑角色 - 权限码: role:edit", 
            "删除菜单 - 权限码: menu:delete"
        ));
        doc.setNotes("按钮类型不需要配置路由路径和组件路径，主要通过菜单编码进行权限判断");
        return doc;
    }
} 

